package com.alexatguigu.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class Alex008LockDemoController {
    
    // 案例1：同一个对象的两个同步方法（对象锁演示）
    @GetMapping("/lock/test1")
    public String test1() {
        Alex008Phone phone = new Alex008Phone();
        
        new Thread(() -> {
            phone.sendEmail();
        }, "EmailThread").start();
        
        try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); }
        
        new Thread(() -> {
            phone.sendSMS();
        }, "SMSThread").start();
        
        return "请查看控制台输出 - 同一对象的两个同步方法";
    }
    
    // 案例2：不同对象的同步方法（对象锁互不影响）
    @GetMapping("/lock/test2")
    public String test2() {
        Alex008Phone phone1 = new Alex008Phone();
        Alex008Phone phone2 = new Alex008Phone();
        
        new Thread(() -> {
            phone1.sendEmail();
        }, "EmailThread").start();
        
        try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); }
        
        new Thread(() -> {
            phone2.sendSMS();
        }, "SMSThread").start();
        
        return "请查看控制台输出 - 不同对象的同步方法";
    }
    
    // 案例3：同一个类的两个静态同步方法（类锁演示）
    @GetMapping("/lock/test3")
    public String test3() {
        Alex008Phone phone = new Alex008Phone();
        
        new Thread(() -> {
            Alex008Phone.staticEmail();
        }, "StaticEmailThread").start();
        
        try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); }
        
        new Thread(() -> {
            Alex008Phone.staticSMS();
        }, "StaticSMSThread").start();
        
        return "请查看控制台输出 - 静态同步方法";
    }
    
    // 案例4：普通同步方法和静态同步方法的关系
    @GetMapping("/lock/test4")
    public String test4() {
        Alex008Phone phone = new Alex008Phone();
        
        new Thread(() -> {
            Alex008Phone.staticEmail();
        }, "StaticEmailThread").start();
        
        try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); }
        
        new Thread(() -> {
            phone.sendSMS();
        }, "NormalSMSThread").start();
        
        return "请查看控制台输出 - 普通同步方法和静态同步方法";
    }
}

// 统一的Phone类
class Alex008Phone {
    // 普通同步方法，锁是当前实例对象this
    public synchronized void sendEmail() {
        System.out.println(Thread.currentThread().getName() + " 开始发送邮件，对象地址：" + this);
        try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
        System.out.println(Thread.currentThread().getName() + " 发送邮件完成");
    }
    
    // 普通同步方法，锁是当前实例对象this
    public synchronized void sendSMS() {
        System.out.println(Thread.currentThread().getName() + " 开始发送短信，对象地址：" + this);
        try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
        System.out.println(Thread.currentThread().getName() + " 发送短信完成");
    }
    
    // 静态同步方法，锁是当前类的Class对象
    public static synchronized void staticEmail() {
        System.out.println(Thread.currentThread().getName() + " 开始发送静态邮件");
        try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
        System.out.println(Thread.currentThread().getName() + " 发送静态邮件完成");
    }
    
    // 静态同步方法，锁是当前类的Class对象
    public static synchronized void staticSMS() {
        System.out.println(Thread.currentThread().getName() + " 开始发送静态短信");
        try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
        System.out.println(Thread.currentThread().getName() + " 发送静态短信完成");
    }
    
    // 普通方法，没有锁
    public void hello() {
        System.out.println(Thread.currentThread().getName() + " 说：hello");
    }
}